// 阿里云OSS分片上传工具（带速度控制）
export default class OssUploader {
  constructor() {
    this.chunkSize = 5 * 1024 * 1024; // 分片大小5MB
    this.speedLimit = 200 * 1024; // 限制上传速度200KB/s
    this.concurrent = 2; // 并发上传的分片数
  }

  // 获取上传签名（调用后端接口）
  async getUploadPolicy(fileName) {
    const res = await uni.request({
      url: '/api/oss/getUploadPolicy',
      data: { fileName },
      method: 'GET'
    });
    return res.data;
  }

  // 计算文件MD5（用于断点续传标识）
  async calculateFileMD5(file) {
    return new Promise((resolve) => {
      const fileReader = new FileReader();
      const spark = new SparkMD5.ArrayBuffer(); // 需要引入spark-md5库
      
      fileReader.onload = (e) => {
        spark.append(e.target.result);
        resolve(spark.end());
      };
      fileReader.readAsArrayBuffer(file);
    });
  }

  // 分片上传（带速度控制）
  async uploadByChunk(file) {
    // 1. 准备工作
    const fileName = file.name;
    const fileSize = file.size;
    const chunkCount = Math.ceil(fileSize / this.chunkSize);
    const fileMd5 = await this.calculateFileMD5(file);
    const policy = await this.getUploadPolicy(fileName);
    
    // 2. 初始化分片上传
    const initResult = await this.initMultipartUpload(policy, fileMd5);
    const uploadId = initResult.UploadId;
    const objectPath = policy.key;

    // 3. 生成所有分片任务
    const chunks = [];
    for (let i = 0; i < chunkCount; i++) {
      const start = i * this.chunkSize;
      const end = Math.min(start + this.chunkSize, fileSize);
      chunks.push({
        index: i,
        start,
        end,
        blob: file.slice(start, end)
      });
    }

    // 4. 并发上传分片（带速度限制）
    const uploadPromises = [];
    const result = [];
    let currentChunk = 0;
    
    // 限速上传函数
    const uploadWithSpeedLimit = async (chunk) => {
      const formData = new FormData();
      formData.append('key', objectPath);
      formData.append('uploadId', uploadId);
      formData.append('partNumber', chunk.index + 1);
      formData.append('file', chunk.blob);
      
      // 计算该分片预计上传时间（根据限速）
      const chunkSize = chunk.end - chunk.start;
      const expectedTime = chunkSize / this.speedLimit * 1000; // 毫秒
      const startTime = Date.now();
      
      // 执行上传
      const response = await uni.uploadFile({
        url: policy.host,
        fileContent: chunk.blob,
        name: 'file',
        formData: {
          key: objectPath,
          uploadId: uploadId,
          partNumber: chunk.index + 1,
          OSSAccessKeyId: policy.accessid,
          signature: policy.signature,
          policy: policy.policy
        }
      });
      
      // 控制速度：如果上传太快，等待剩余时间
      const actualTime = Date.now() - startTime;
      if (actualTime < expectedTime) {
        await new Promise(resolve => setTimeout(resolve, expectedTime - actualTime));
      }
      
      return {
        PartNumber: chunk.index + 1,
        ETag: JSON.parse(response.data).ETag
      };
    };

    // 并发控制
    while (currentChunk < chunkCount) {
      const batch = chunks.slice(currentChunk, currentChunk + this.concurrent);
      const batchResults = await Promise.all(batch.map(uploadWithSpeedLimit));
      result.push(...batchResults);
      currentChunk += this.concurrent;
      
      // 触发进度回调（当前已上传大小）
      const uploadedSize = currentChunk * this.chunkSize;
      this.onProgress(uploadedSize / fileSize * 100);
    }

    // 5. 完成分片上传
    return this.completeMultipartUpload(policy, objectPath, uploadId, result);
  }

  // 初始化分片上传
  async initMultipartUpload(policy, fileMd5) {
    const response = await uni.request({
      url: `${policy.host}/?uploads`,
      method: 'POST',
      header: {
        'Authorization': `OSS ${policy.accessid}:${policy.signature}`,
        'Content-Type': 'application/json'
      }
    });
    return response.data;
  }

  // 完成分片上传
  async completeMultipartUpload(policy, objectPath, uploadId, parts) {
    const completeData = {
      CompleteMultipartUpload: {
        Parts: parts.sort((a, b) => a.PartNumber - b.PartNumber)
      }
    };
    
    const response = await uni.request({
      url: `${policy.host}/${objectPath}?uploadId=${uploadId}`,
      method: 'POST',
      data: completeData,
      header: {
        'Authorization': `OSS ${policy.accessid}:${policy.signature}`,
        'Content-Type': 'application/json'
      }
    });
    return response.data;
  }

  // 进度回调
  onProgress(percent) {
    console.log(`上传进度：${percent.toFixed(2)}%`);
  }
}
    